package tools

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/util/gconv"
	"github.com/shopspring/decimal"
	"go-gui/frame/log"
	"os"
	"reflect"
	"strings"
)

func CreateDir(dir string) {
	exist, err := PathExists(dir)
	if err != nil {
		log.Error(err)
		return
	}

	if exist {
		log.Error(errors.New("文件夹已存在！"))
	} else {
		// 创建文件夹
		err := os.Mkdir(dir, os.ModePerm)
		if err != nil {
			log.Error(err)
		}
	}
}

// 判断文件夹是否存在
func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

func JsonToMap(jsonStr string) map[string]interface{} {
	var mapResult map[string]interface{}
	err := json.Unmarshal([]byte(jsonStr), &mapResult)
	if err != nil {
		log.Error(err)
	}
	return mapResult
}

// Dump 调试打印数据
func Dump(data interface{}, name ...string) {
	if data == nil {
		data = "null"
	}
	if len(name) == 0 {
		g.Dump(data)
	} else {
		typeOf := reflect.TypeOf(data)
		fmt.Println(name[0] + typeOf.String())
		g.Dump(data)
		fmt.Println(name[0])
	}
}

// StringToArray 字符串转切片
func StringToArray(str string, sep string) []string {
	return strings.Split(str, sep)
}

// StringToArrayInt64 字符串转切片
func StringToArrayInt64(str string, sep string) []int64 {
	strArr := StringToArray(str, sep)
	return gconv.Int64s(strArr)
}

// ArrayInt64ToString 切片转字符串
func ArrayInt64ToString(arr []int64, sep string) string {
	str := ""
	if len(arr) == 0 {
		return str
	}
	for _, v := range arr {
		if str == "" {
			str = gconv.String(v)
		} else {
			str += sep + gconv.String(v)
		}
	}
	return str
}

// ArrayToString 切片转字符串
func ArrayToString(arr []string, sep string) string {
	str := ""
	if len(arr) == 0 {
		return str
	}
	for _, v := range arr {
		if str == "" {
			str = v
		} else {
			str += sep + v
		}
	}
	return str
}

// GetFieldsByStruct 根据结构体获取fields
func GetFieldsByStruct(pointer interface{}) string {
	t := reflect.TypeOf(pointer).Elem()
	fields := ""
	for i := 0; i < t.NumField(); i++ {
		fileArr := StringToArray(t.Field(i).Tag.Get("orm"), ",")
		if fileArr[0] != "" {
			if fields == "" {
				fields += "`" + fileArr[0] + "`"
			} else {
				fields += ",`" + fileArr[0] + "`"
			}
		}
	}
	return fields
}

// GetLimit 获取limit
func GetLimit(page int64, pageNum int64) (int64, int64) {
	if page == 0 || page == 1 {
		return 0, pageNum
	}
	return (page-1)*pageNum + 1, pageNum
}

// PageInit 分页初始化
func PageInit(page, limit int, defPageParam ...int) (int, int) {
	defLen := len(defPageParam)
	defPage := 1
	defLimit := 20
	switch defLen {
	case 0:

	case 1:
		defPage = defPageParam[0]
	case 2:
		defPage = defPageParam[0]
		defLimit = defPageParam[1]
	default:
		defPage = defPageParam[0]
		defLimit = defPageParam[1]
	}
	if page <= 0 {
		page = defPage
	}
	if limit <= 0 {
		limit = defLimit
	}
	return page, limit
}

// Sprint 四舍五入保留 bit位 小数
func Sprint(floatNum float64, bit int32) float64 {
	float := decimal.NewFromFloat(floatNum).StringFixed(bit)
	return gconv.Float64(float)
}

// AllInArr 判断字符串枚举的每一项是否在这个数组里
// 1,2,3 是否全部在 [{"id":1},{"id",2}]  false  3不在
func AllInArr(listStr string, sep string, arr interface{}, filed string) bool {
	strArr := StringToArray(listStr, sep)
	arrString := gconv.SliceMapDeep(arr)
	for _, v := range strArr {
		for _, vg := range arrString {
			if gconv.String(vg[filed]) != v {
				return false
			}
		}
	}
	return true
}

// InArrayInt64 判断数字是否在数组里
func InArrayInt64(number int64, arr []int64) bool {
	for _, v := range arr {
		if number == v {
			return true
		}
	}
	return false
}

// InArrayString 判断字符串是否在数组里
func InArrayString(str string, arr []string) bool {
	for _, v := range arr {
		if str == v {
			return true
		}
	}
	return false
}

// RemoveArrayByVal 根据val删除数组中的值
func RemoveArrayByVal(arr []string, val string) []string {
	newArr := []string{}
	for _, v := range arr {
		if v != val {
			newArr = append(newArr, v)
		}
	}
	return newArr
}

// RemoveArrayByKey 根据key删除数组中的值
func RemoveArrayByKey(arr []string, key int) []string {
	return append(arr[:key], arr[key+1:]...)
}

// ReplenishStr 不足位数补充字符串
func ReplenishStr(str interface{}, repStr string, amount int) string {
	newStr := gconv.String(str)
	strLen := len(newStr)
	if strLen < amount {
		for i := 0; i < amount-strLen; i++ {
			newStr = repStr + newStr
		}
	}
	return newStr
}
